package edu.mit.csail.relo.store;

import org.openrdf.model.Resource;
import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.sesame.sail.StatementIterator;

/**
 * @author Elizabeth L. Murnane
 */

public class StoreUnionRepository extends ReloRdfRepository {
	
	private ReloRdfRepository storeRepo;
	private ReloRdfRepository cacheRepo;
	
	public StoreUnionRepository(ReloRdfRepository repository) {
		super(repository.sailRepo);
		storeRepo = repository;
	}
	
	public void setStoreRepo(ReloRdfRepository storeRepo) {
		this.storeRepo = storeRepo;
	}
	
	public ReloRdfRepository getStoreRepo() {
		return storeRepo;
	}
	
    // Cache repo allows for the diagram to be drawn the way it was saved
    
    public void setCacheRepo(ReloRdfRepository cacheRepo) {
		this.cacheRepo = cacheRepo;
	}
	
	public ReloRdfRepository getCacheRepo() {
		return cacheRepo;
	}	
	
	@Override
	public StatementIterator getStatements(Resource subj, URI pred, Value obj) {
		ReloRdfRepository memRep = StoreUtil.getMemRepository();
		StatementIterator it1 = storeRepo.getStatements(subj, pred, obj);
		while (it1.hasNext()) {
			Statement stmt = it1.next();
			memRep.startTransaction();
			memRep.addStatement(stmt.getSubject(), stmt.getPredicate(), stmt.getObject());
			memRep.commitTransaction();
		}
		it1.close();
		if (cacheRepo==null) return memRep.getStatements(subj, pred, obj);
		
		StatementIterator it2 = cacheRepo.getStatements(subj, pred, obj);
		while (it2.hasNext()) {
			Statement stmt = it2.next();
			memRep.startTransaction();
			memRep.addStatement(stmt.getSubject(), stmt.getPredicate(), stmt.getObject());
			memRep.commitTransaction();
		}
		it2.close();
		return memRep.getStatements(subj, pred, obj);
	}
	
	@Override
	public Statement getStatement(Resource subj, URI pred, Value obj) {
		if(cacheRepo!=null) {
			StatementIterator cacheStmts = cacheRepo.getStatements(subj, pred, obj); 
			if (cacheStmts.hasNext()) {
				Statement retVal = cacheStmts.next();
				cacheStmts.close();
				return retVal;
			}
		}
		StatementIterator storeStmts = storeRepo.getStatements(subj, pred, obj);
		if (storeStmts.hasNext()) {
			Statement retVal = storeStmts.next();
			storeStmts.close();
			return retVal;
		}
		return nullStatement; 
	}
	
	@Override
	public boolean hasStatement(Resource subj, URI pred, Value obj) {
		if(storeRepo.hasStatement(subj, pred, obj)) return true;
		if(cacheRepo!=null && cacheRepo.hasStatement(subj, pred, obj)) return true;
		return false;
	}
	
}
